package com.ruoyi.miniapp.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.WeChatUtil;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.miniapp.ali.NanoIdUtil;
import com.ruoyi.miniapp.ali.SequenceCodesUtil;
import com.ruoyi.miniapp.ali.StrHexStrUtil;
import com.ruoyi.miniapp.config.WeChatMiniappProperty;
import com.ruoyi.miniapp.domain.BasAdvertiser;
import com.ruoyi.miniapp.domain.BasMaintainerApply;
import com.ruoyi.miniapp.domain.DiscountsScope;
import com.ruoyi.miniapp.domain.TCodeAdministrativeDivision;
import com.ruoyi.miniapp.domain.TrainingAddress;
import com.ruoyi.miniapp.dto.ArgumentsDto;
import com.ruoyi.miniapp.dto.TrainingAddressDto;
import com.ruoyi.miniapp.mongo.WxUserHandler;
import com.ruoyi.miniapp.service.IBasAdvertiserService;
import com.ruoyi.miniapp.service.IBasMaintainerApplyService;
import com.ruoyi.miniapp.service.IDiscountsScopeService;
import com.ruoyi.miniapp.service.IRealNameAuthInfoService;
import com.ruoyi.miniapp.service.ITCodeAdministrativeDivisionService;
import com.ruoyi.miniapp.service.ITrainingAddressService;
import com.ruoyi.miniapp.service.ITsalesmanService;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.RealNameAuthInfo;
import com.tdd.wx.users.entity.WxUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

@Api(tags = "在线报名")
@RestController
@RequestMapping("MaintainerApply")
public class MaintainerApplyController {

    private final Logger logger = LoggerFactory.getLogger(MaintainerApplyController.class);

    @Autowired
    private WxUserHandler wxUserHandler;

    @Autowired
    private WeChatMiniappProperty weChatMiniappProperty;

    @Autowired
    private ITrainingAddressService trainingAddressService;

    @Autowired
    private IBasAdvertiserService basAdvertiserService;

    @Autowired
    private IBasMaintainerApplyService maintainerApplyService;

    @Autowired
    private IRealNameAuthInfoService realNameAuthInfoService;

    @Autowired
    private ITCodeAdministrativeDivisionService administrativeDivisionService;

    @Autowired
    private IDiscountsScopeService discountsScopeService;

    @Autowired
    private ITsalesmanService tsalesmanService;


    /**
     *
     * @param type  屏幕还是袋身 折扣类型1=屏幕   2=袋身
     * @return
     */
    @ApiOperation("查询套餐列表")
    @GetMapping("getDiscountsScopeInfo/{type}")
    public AjaxResult getDiscountsScopeInfo(@PathVariable Integer type) {
        //查询套餐
        List<DiscountsScope> discountsScopeInfo = discountsScopeService.getDiscountsScopeBytype(type);
        return AjaxResult.success(discountsScopeInfo);
    }

    @ApiOperation("设置用户签到")
    @PostMapping(value = "setUserSignIn",consumes = MediaType.APPLICATION_JSON_VALUE)
    public AjaxResult setUserSignIn(@RequestBody() JSONObject jsonObject ) {
        //修改报名表
        Integer addressId = jsonObject.getInteger("addressId");
        if(addressId==null)
        {
            return AjaxResult.error("参数错误：addressId");
        }
        BasMaintainerApply basMaintainerApplyByUserId = maintainerApplyService.getBasMaintainerApplyByUserId();
        if(basMaintainerApplyByUserId==null)
        {
            return AjaxResult.error("您还未报名");
        }
        Integer myAdressId = null;
        if(basMaintainerApplyByUserId.getAddressId()!=null)
        {
            myAdressId = basMaintainerApplyByUserId.getAddressId();
        }
        else
        {
            myAdressId = basMaintainerApplyByUserId.getNewAddress();
        }

        if(myAdressId!=null){
            if(!addressId.equals(myAdressId))
            {
                return AjaxResult.error("您未报名改场次培训");
            }
            basMaintainerApplyByUserId.setSigninDate(new Date());
            basMaintainerApplyByUserId.setState(3);
            AjaxResult ajaxResult = maintainerApplyService.updateBasMaintainerApplyByUserId(basMaintainerApplyByUserId);
            return ajaxResult;
        }
        else
        {
            return AjaxResult.error("未找到对应培训场次");
        }
    }

    @ApiOperation("查看培训地址")
    @GetMapping("getTrainingAddressInfo/{divisionCode}")
    public AjaxResult getTrainingAddressInfo(@PathVariable String divisionCode) {
        //小程序
        AjaxResult trainingAddressInfo = trainingAddressService.getTrainingAddressInfoOne(divisionCode);
        return trainingAddressInfo;
    }

    @ApiOperation("查询培训概要信息（第一个页面)")
    @GetMapping("getTrainingResume")
    public AjaxResult getTrainingResume()
    {
        List<TrainingAddress> cityList = trainingAddressService.getCityList();
        if(!ObjectUtils.isEmpty(cityList))
        {
            Map<String,Object> ret = new HashMap<>(1);
            for(TrainingAddress trainCity : cityList){
                if(trainCity.getFkDivisionCode()!=null && trainCity.getDivisionName()!=null){
                    Map<String,Object> city = new HashMap<>(2);
                    ret.put(trainCity.getFkDivisionCode(), city);
                    city.put("City",trainCity.getDivisionName());
                    List<TrainingAddress> trainingAddressInfoList = trainingAddressService.getTrainingAddressInfoList(trainCity.getFkDivisionCode());
                    city.put("TrainBase",trainingAddressInfoList);
                }
            }
            return AjaxResult.success(ret);
        }
        return AjaxResult.success(new HashMap<>(0));
    }

    @ApiOperation("查看培训场次")
    @PostMapping(value = "getTrainingBytrainingName",consumes = MediaType.APPLICATION_JSON_VALUE)
    public AjaxResult getTrainSession(@RequestBody() JSONObject trainingName) {
        //小程序
//        String token = SecurityUtils.getToken();
        String trainingName1 = (String) trainingName.get("trainingName");
        AjaxResult addressInfoBytrainingName = trainingAddressService.getTrainingAddressInfoBytrainingName(trainingName1);
        return addressInfoBytrainingName;
    }

    @ApiOperation("选择场次返回用户报名信息")
    @GetMapping("getUserInfo/{id}")
    public AjaxResult getUserInfo(@PathVariable("id") Integer id) {
        //小程序
        AjaxResult userInfo = trainingAddressService.getUserInfo(id);
        return userInfo;
    }

    @ApiOperation("付款前验证是否是服务商")
    @GetMapping("examineMaintainer")
    public AjaxResult examineMaintainer() {
        //小程序
        Long userId = SecurityUtils.getUserId();
        RealNameAuthInfo realNameAuthInfo = realNameAuthInfoService.selRealNameAuth(userId);
        if (ObjectUtils.isEmpty(realNameAuthInfo)) {
            return AjaxResult.error("抱歉您还不是服务商,无法报名，请先去注册服务商！");
        } else {
            return AjaxResult.success("true");
        }
    }

    @ApiOperation("保存报名信息")
    @PostMapping("signUp")
    public AjaxResult signUp(@RequestBody BasMaintainerApply obj) {
        String unionId = SecurityUtils.getUnionId();
        WxUser wxUser = wxUserHandler.findByUnionId(unionId);
        if(wxUser == null)
        {
            return AjaxResult.error("请先登录");
        }
        Long userId = wxUser.getSysUserId();
        String openId = SecurityUtils.getOpenId();
        if(ObjectUtils.isEmpty(openId))
        {
            logger.debug("openID为空...");
        }
        if(userId == null || userId == 0L)
        {
            return AjaxResult.error("请先登录");
        }
        if(userId == 100L)
        {
            return AjaxResult.error("请先去注册服务商");
        }


        BasMaintainerApply searchArg = new BasMaintainerApply();
        searchArg.setUserId(userId);
        if(maintainerApplyService.getBasMaintainerApplyCount(searchArg)>0)
        {
            List<BasMaintainerApply> basMaintainerApplyList = maintainerApplyService.getBasMaintainerApplyList(searchArg);
            for(BasMaintainerApply maintainerApply : basMaintainerApplyList){
                if(maintainerApply.getAccomplishDate()==null)
                {
                    maintainerApplyService.deleteBasMaintainerApply(maintainerApply.getApplyId());
                    logger.debug("删除未付款培训订单：{}",maintainerApply.getApplyId());
                }
                else
                {
                    /***
                     * 存在已付款并且已考核成功的订单
                     */
                    if(maintainerApply.getState() ==2){
                        logger.debug("存在已付款培训订单：{}", maintainerApply.getApplyId());
                        return AjaxResult.error("存在已付款培训订单：{}", maintainerApply.getApplyId());
                    }
                }
            }
        }

        String str = NanoIdUtil.randomLongNanoId("MA",32);
        obj.setApplyId(str);
        obj.setCreateDate(LocalDateTime.now());
        obj.setState(0);
        obj.setUserId(userId);
        //小程序
        if(ObjectUtils.isEmpty(obj.getAddressId()))
        {
            return AjaxResult.error("请选择培训场次");
        }
        TrainingAddressDto trainingAddress = trainingAddressService.getTrainingAddressByKey(obj.getAddressId());
        if(ObjectUtils.isEmpty(trainingAddress) || trainingAddress.getSurplusPlaces()<=0)
        {
            return AjaxResult.error("未找到相应培训场次，或已无培训名额");
        }
        obj.setTotalPrice(trainingAddress.getExpense());
        int count = maintainerApplyService.insertBasMaintainerApply(obj);
        trainingAddressService.updateSurplusPlacesB(obj.getAddressId());
        if (count > 0) {
            return AjaxResult.success("报名成功！");
        } else {
            return AjaxResult.error("报名失败！");
        }
    }

    @ApiOperation("保存报名信息")
    @PostMapping("addApplyInfo")
    public AjaxResult addApplyInfo(@RequestBody BasMaintainerApply obj) {
        String str = NanoIdUtil.randomLongNanoId("MA",32);
        obj.setApplyId(str);
        //小程序
        int count = maintainerApplyService.insertBasMaintainerApply(obj);
        if (count > 0) {
            return AjaxResult.success("报名成功！");
        } else {
            return AjaxResult.error("报名失败！");
        }
    }

    @ApiOperation("报名之后查询用户报名信息")
    @GetMapping("getUserTrainInfo")
    public AjaxResult getUserTrainInfo() {
        //小程序
        BasMaintainerApply maintainerApply = maintainerApplyService.getBasMaintainerApplyByUserId();
        Long userId = SecurityUtils.getUserId();
        if(userId == null)
        {
            return AjaxResult.error("请先登录");
        }
        String applyId = null;
        Map<String,Object> ret = new HashMap<>(1);
        int state=9; //0:报名，1，考核不通过 2，考核完成 3.签到，9：未报名
        ret.put("state",state);
        if(maintainerApply!=null){
            if(maintainerApply.getAccomplishDate()==null)
            {
                maintainerApply = null;
                return AjaxResult.success(ret);
            }

            Integer addressId = null;
            if(maintainerApply.getNewAddress()!=null)
            {
                addressId = maintainerApply.getNewAddress();
                logger.debug("使用新培训场次：{}",addressId);
            }
            else
            {
                addressId = maintainerApply.getAddressId();
                logger.debug("给定培训场次：{}",addressId);
            }
            ret.put("state",maintainerApply.getState());
            //ret.put("apply", maintainerApply);
            if(addressId!=null){
                TrainingAddressDto trainingAddressByKey = trainingAddressService.getTrainingAddressByKey(addressId);
                if(trainingAddressByKey != null){
                    trainingAddressByKey.setApplyId(maintainerApply.getApplyId());
                    trainingAddressByKey.setCertificateNo(maintainerApply.getCertificateNo());
                    RealNameAuthInfo realNameAuthInfo = realNameAuthInfoService.selRealNameAuth(userId);
                    if(!ObjectUtils.isEmpty(realNameAuthInfo)){
                        logger.debug("有实名信息");
                        trainingAddressByKey.setUserName(realNameAuthInfo.getRealName());
                        trainingAddressByKey.setUserPhone(realNameAuthInfo.getTel());
                    }
                    else
                    {
                        logger.debug("无实名信息");
                    }
                    ret.put("address", trainingAddressByKey);
                }
                else
                {
                    return AjaxResult.error("未找到对应报名场次！");
                }
            }
            else
            {
                return AjaxResult.error("报名信息未关联培训场次！");
            }
        }
        return AjaxResult.success(ret);
    }


    @ApiOperation("修改用户报名地址")
    @PostMapping(value = "updateUserTrainAddress", produces = "application/json;charset=utf-8")
    public AjaxResult updateUserTrainAddress(@RequestBody BasMaintainerApply obj) {
        //查询用户是否已修改过地址
        BasMaintainerApply maintainerApply = maintainerApplyService.getBasMaintainerApplyByKey(obj.getApplyId());
        if (maintainerApply.getNewAddress() != null) {
            return AjaxResult.success("抱歉，无法再修改地址！");
        } else {
            // DateTimeFormatter.ofPattern方法根据指定的格式输出时间
            LocalDateTime dateTime = LocalDateTime.now();
            obj.setAmendDate(dateTime);
            Long userId = SecurityUtils.getUserId();
            obj.setOperatorId(userId);
            int count = maintainerApplyService.updateBasMaintainerApply(obj);
            //剩余名额+ -
            trainingAddressService.updateSurplusPlacesA(obj.getAddressId());
            trainingAddressService.updateSurplusPlacesB(obj.getNewAddress());
            if (count > 0) {
                return AjaxResult.success("修改成功！");
            } else {
                return AjaxResult.error("修改失败！");
            }
        }
    }

    @ApiOperation("用户考核")
    @PostMapping("updateUserExamine")
    public AjaxResult updateUserExamine(@RequestBody BasMaintainerApply obj) {
        Long userId = SecurityUtils.getUserId();
        LocalDateTime now = LocalDateTime.now();
        String newStr = "";
        String fkDivisionCode = null;
        TrainingAddressDto trainingAddress = trainingAddressService.getTrainingAddressByKey(obj.getAddressId());
        fkDivisionCode = trainingAddress.getFkDivisionCode();
        //截取第一个字符 武汉市(WHS)  W
        TCodeAdministrativeDivision division = administrativeDivisionService.selectTCodeAdministrativeDivisionByPkDivisionCode(fkDivisionCode);//obj.getFkDivisionCode());
        String pinYinChar = String.valueOf(SequenceCodesUtil.getPinYinHeadChar(division.getDivisionName()).charAt(0));
        //获取用户身份证号
        RealNameAuthInfo realNameAuthInfo = realNameAuthInfoService.selRealNameAuth(obj.getUserId());
        String idCard = realNameAuthInfo.getIdCard();
        //截取身份证号 并转换16进制
        String idCardone = idCard.substring(0, 2);
        String idCardone1 = idCard.substring(2, 4);
        String idCardone2 = idCard.substring(4, 6);
        String idCardone3 = idCard.substring(6, 10);
        String idCardone4 = idCard.substring(10, 12);
        String idCardone5 = idCard.substring(12, 14);
        String idCardone6 = idCard.substring(14, 18);
        //截取身份证号 并转换16进制 去空格
        String s = StrHexStrUtil.str2HexStr(idCardone).replaceAll(" +", "");
        String s1 = StrHexStrUtil.str2HexStr(idCardone1).replaceAll(" +", "");
        String s2 = StrHexStrUtil.str2HexStr(idCardone2).replaceAll(" +", "");
        String s3 = StrHexStrUtil.str2HexStr(idCardone3).replaceAll(" +", "");
        String s4 = StrHexStrUtil.str2HexStr(idCardone4).replaceAll(" +", "");
        String s5 = StrHexStrUtil.str2HexStr(idCardone5).replaceAll(" +", "");
        //判断审核不通过
        if (obj.getEvaluationResult() == 2) {
            //考核人id
            obj.setAssessUserId(userId);
            //审核时间
            obj.setEvaluationDate(now);
            int count = maintainerApplyService.updateBasMaintainerApply(obj);
            if (count > 0) {
                return AjaxResult.success("修改成功！");
            } else {
                return AjaxResult.error("修改失败！");
            }
        } else {
            //判断用户是否是广告主
            BasAdvertiser basAdvertiser = basAdvertiserService.selectBasAdvertiserByUserId(obj.getUserId());
            if (ObjectUtils.isEmpty(basAdvertiser)) {
                //实例化广告主用户表
                BasAdvertiser advertiser = new BasAdvertiser();
                realNameAuthInfo.setRoleType(30L);
                realNameAuthInfo.setCreateTime(new Date());
                //添加广告主实名信息
                realNameAuthInfoService.insertRealNameAuthInfo(realNameAuthInfo);
                //添加广告主信息
                advertiser.setUserId(obj.getUserId());
                advertiser.setFkUnionId(realNameAuthInfo.getUnionid());
                advertiser.setFkDivisionCode(fkDivisionCode);//obj.getFkDivisionCode());
                basAdvertiserService.insertBasAdvertiser(advertiser);
            }
            //毕业编号
            newStr = pinYinChar + s + s1 + s2 + s3 + s4 + s5;
            //获取用户毕业编号二维码保存
            AjaxResult save = maintainerApplyService.save("毕业编号二维码", newStr, 240, 240);
            String admCurrent = new Gson().toJson(save.get("data"));
            JSONObject jsonObject = JSON.parseObject(admCurrent);
            String pkResId = jsonObject.getString("pkResId");
            //获取屏幕折扣    表：discounts_scope
            DiscountsScope discountsScopeByid = discountsScopeService.getDiscountsScopeByid(obj.getType1());
            //获取袋身折扣    表：discounts_scope
            DiscountsScope discountsScopeByid2 = discountsScopeService.getDiscountsScopeByid(obj.getType2());
            //保存用户id
            discountsScopeByid.setUserId(obj.getUserId());
            discountsScopeByid2.setUserId(obj.getUserId());
            //保存二维码资源
            obj.setQrcodeId(pkResId);
            //审核时间
            obj.setEvaluationDate(now);
            //毕业编号
            obj.setCertificateNo(newStr);
            //考核人id
            obj.setAssessUserId(userId);
            //储存服务商（业务员）折扣表   表: t_salesman
            tsalesmanService.insertTsalesman(discountsScopeByid);
            tsalesmanService.insertTsalesman(discountsScopeByid2);
            int count = maintainerApplyService.updateBasMaintainerApply(obj);
            if (count > 0) {
                return AjaxResult.success("修改成功！");
            } else {
                return AjaxResult.error("修改失败！");
            }
        }
    }

    /**
     * 分页查询 培训基地
     *
     * @return
     */
    @ApiOperation("查询培训基地信息")
    @PostMapping("getPageTrainingAddress")
    public AjaxResult getPageTrainingAddress(@RequestBody TrainingAddress obj) {
        AjaxResult pageTrainingAddress = trainingAddressService.getPageTrainingAddress(obj);
        return pageTrainingAddress;
    }

    @ApiOperation("修改培训地址信息")
    @PostMapping("updateTrainAddressInfo")
    public AjaxResult updateTrainAddress(@RequestBody TrainingAddress obj) {
//        obj.setSurplusPlaces(obj.getPlaces());
        int count = trainingAddressService.updateTrainingAddress(obj);
        if (count > 0) {
            return AjaxResult.success("修改成功！");
        } else {
            return AjaxResult.error("修改失败！");
        }
    }

    @ApiOperation("删除培训地址")
//    @PostMapping("deleteTrainingAddress/{id}")
    public AjaxResult deleteTrainingAddress(@PathVariable Integer id) {
        AjaxResult ajaxResult = trainingAddressService.deleteTrainingAddress(id);
        return ajaxResult;
    }

    @ApiOperation("新增培训地址")
    @PostMapping("insertTrainAddress")
    public AjaxResult insertTrainAddress(@RequestBody TrainingAddress obj) {
        obj.setSurplusPlaces(obj.getPlaces());
        int count = trainingAddressService.insertTrainingAddress(obj);
        if (count > 0) {
            return AjaxResult.success("新增成功！");
        } else {
            return AjaxResult.error("新增失败！");
        }
    }

    @ApiOperation("选择市级城市")
    @GetMapping("selCityList")
    public AjaxResult selCityList() {
        AjaxResult selCityList = trainingAddressService.selCityList();
        return selCityList;
    }

    /**
     * 运维后台
     * #根据市级编码查询下面有多少培训基地
     */
    @ApiOperation("根据市级编码查询培训基地和场次")
    @GetMapping("selTrainingNameList/{fkDivisionCode}")
    public AjaxResult selTrainingNameList(@PathVariable String fkDivisionCode) {
        AjaxResult ajaxResult = trainingAddressService.selTrainingNameList(fkDivisionCode);
        return ajaxResult;
    }

    /**
     * 运维后台
     * #根据培训基地名称查询场次
     */
    @ApiOperation("根据培训基地名称查询场次")
//    @GetMapping("selTrainingAddressList/{teainingName}")
    public AjaxResult selTrainingAddressList(@PathVariable String teainingName) {
        AjaxResult ajaxResult = trainingAddressService.selTrainingAddressList(teainingName);
        return ajaxResult;
    }

    /**
     * 运维后台
     * #根据场次查询用户信息
     *
     * @return
     */
    @ApiOperation("根据场次查询用户信息")
    @PostMapping("getUserInfoList")
    public AjaxResult getUserInfoList(@RequestBody ArgumentsDto obj) {
        AjaxResult userInfoList = maintainerApplyService.getUserInfoList(obj);
        return userInfoList;
    }

    @ApiOperation("生成预支付订单")
    @GetMapping("toPay")
    public R toPay(){
        String unionid = SecurityUtils.getUnionId();
        String openId = SecurityUtils.getOpenId();
        WxUser wxUser = wxUserHandler.findByUnionId(unionid);

//        LoginUser loginUser = SecurityUtils.getLoginUser();
//        logger.debug("getLoginUser:{}:UserKey:{}",loginUser.toString(),SecurityUtils.getUserKey());
//        Map<String, Object> localMap = SecurityContextHolder.getLocalMap();
//        logger.debug("localMap:{}",localMap);
        if(ObjectUtils.isEmpty(wxUser))
        {
            logger.error("生成预支付订单失败==》NoWxUserInfo");
            return R.fail("生成预支付订单失败==》NoWxUserInfo");
        }

        Long userId = wxUser.getSysUserId();
        if(ObjectUtils.isEmpty(openId))
        {
            logger.error("生成预支付订单失败==》未找到OpenId信息={}",openId);
            return R.fail("生成预支付订单失败==》未找到OpenId信息");
        }
        if(ObjectUtils.isEmpty(userId))
        {
            logger.error("生成预支付订单失败==》未找到登录信息");
            return R.fail("生成预支付订单失败==》未找到登录信息");
        }
        BasMaintainerApply applyInfo = maintainerApplyService.getBasMaintainerApplyByUserIdNoPay(userId);
        if(ObjectUtils.isEmpty(applyInfo))
        {
            logger.error("生成预支付订单失败==》未找到对应的订单");
            return R.fail("生成预支付订单失败==》未找到对应的订单");
        }

        String outTradeNo = DateTime.now().toString("yyyyMMddHHmmsss")+ RandomUtil.randomNumbers(4);
        applyInfo.setOrderNum(outTradeNo);
        maintainerApplyService.updateBasMaintainerApply(applyInfo);

        //生成预支付订单
        try {
            BigDecimal totalPrice = applyInfo.getTotalPrice().multiply(new BigDecimal(100));
            Map prePayRes = WeChatUtil.payUnifiedorderMA(weChatMiniappProperty.getAppid(),"淘袋袋-服务商培训",applyInfo.getOrderNum(),totalPrice.longValue(),openId);
            if(prePayRes == null){
                return R.fail();
            }
            logger.debug(prePayRes.toString());
            Map<String,Object> signParam = new HashMap<>();
            signParam.put("appId",weChatMiniappProperty.getAppid());
            signParam.put("nonceStr", MapUtil.getStr(prePayRes,"nonce_str"));
            signParam.put("package","prepay_id="+MapUtil.getStr(prePayRes,"prepay_id"));
            signParam.put("timeStamp",DateTime.now().getTime()+"");
            signParam.put("signType","MD5");
            String paySign = WeChatUtil.getSign(signParam);
            signParam.put("paySign",paySign);
            return R.ok(signParam);
        }catch (Exception e){
            logger.error("生成预支付订单失败==》"+e.getMessage());
            return R.fail("生成预支付订单失败==》"+e.getMessage());
        }
    }

    @PostMapping("/open/wxPayNotify")
    public void wxPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
        logger.info("进入支付回调！");
        BufferedReader reader = null;
        String xmlStr = null;
        reader = request.getReader();
        String line = null;
        StringBuffer sb = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        xmlStr = sb.toString();
        Map map = XmlUtil.xmlToMap(xmlStr);
        String outTradeNo = MapUtil.getStr(map,"out_trade_no",null);
        logger.info("支付回调====》"+outTradeNo);
        BasMaintainerApply maintainerApply = maintainerApplyService.getBasMaintainerApplyByOrderNum(outTradeNo);
        if(maintainerApply != null){
            maintainerApply.setAccomplishDate(LocalDateTime.now());
            TrainingAddressDto trainingAddressByKey = trainingAddressService.getTrainingAddressByKey(maintainerApply.getAddressId());
            String certNo = trainingAddressByKey.getFkDivisionCode().substring(0,4).toUpperCase() + String.format("%0" + 4 + "X", trainingAddressByKey.getId()).toUpperCase()
                    + String.format("%0" + 4 + "X", trainingAddressByKey.getSurplusPlaces()).toUpperCase();
            maintainerApply.setCertificateNo(certNo);
            maintainerApplyService.updateBasMaintainerApply(maintainerApply);
            return;
        }else {
            response.setStatus(500);
            //获取输出流
            PrintWriter out = response.getWriter();
            Map rtMap = new HashMap();
            rtMap.put("code","FAIL");
            rtMap.put("message","失败");
            out.println(JSONUtil.toJsonStr(rtMap));
        }
    }
}
